#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <cstdlib>
#include <unistd.h>
#include <strings.h>
#include <string.h>

#include <netinet/in.h>
#include <arpa/inet.h>

using namespace std;

void Usage(string proc)
{
    cout << "\n\tUsage:" << proc << "port[1024+ ]\n"
         << endl;
}
int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        Usage(argv[0]);
        exit(0);
    }

    string serverip = argv[1];
    uint16_t serverport = stoi(argv[2]);

    //创建服务端的套接字信息
    struct sockaddr_in server;
    bzero(&server, sizeof(server));
    server.sin_family = AF_INET;
    server.sin_port = htons(serverport);
    server.sin_addr.s_addr = inet_addr(serverip.c_str());
    socklen_t len = sizeof(server);


    // int socket(int domain, int type, int protocol);
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    // 使用ipv4协议、面向用户数据报、协议段为0
    if (sockfd < 0)
    {
        cout << "socker error" << endl;
        return 1;
    }

    // 创建好套接字后，客户端也需要绑定套接字
    // （客户端也需要自己的端口号和ip——便于服务端定位）
    // 不过不需要用户自己绑定，由操作系统自由选择绑定（数字不重要，重要的是唯一性）
    // 不能绑定同一个端口号
    //   总结：服务端的端口号唯一（客户端需要定位唯一的服务端）
    //        客户端的端口号随机（需要适配不同的服务端服务）

    // 在首次发送数据sendto时，绑定
    string message;
    char buffer[1024];
    while (true)
    {
        // 发送报文
        cout << "Please Enter>>";
        getline(cin, message);

        cout << "test input: " << message << endl;
        sendto(sockfd, message.c_str(), message.size(), 0, (struct sockaddr *)&server, len);


        struct sockaddr_in temp;
        socklen_t len = sizeof(temp);
        size_t s = recvfrom(sockfd, buffer, 1023, 0, (sockaddr*)&temp, &len);
        if(s > 0)// s > 0收消息成功
        {
            buffer[s] = 0;
            cout << buffer << endl;
        }
    }

    close(sockfd);
    return 0;
}